package com.xiaobai.frame.service.impl;

import cn.hutool.core.lang.UUID;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaobai.common.utils.result.R;
import com.xiaobai.common.utils.result.Result;
import com.xiaobai.common.utils.result.ResultCode;
import com.xiaobai.common.utils.tool.AuthUtil;
import com.xiaobai.common.utils.tool.Func;
import com.xiaobai.common.utils.tool.UserInfo;
import com.xiaobai.frame.entity.ClientDetails;
import com.xiaobai.frame.entity.DTO.PageDTO;
import com.xiaobai.frame.entity.VO.userVO.login.LoginVO;
import com.xiaobai.frame.mapper.ClientDetailsMapper;
import com.xiaobai.frame.service.IClientDetailsService;
import com.xiaobai.frame.utils.RedisTool;
import com.xiaobai.frame.utils.TokenStorageUtil;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;

import static com.xiaobai.frame.utils.RedisKey.GET_CODE;

/**
 * <p>
 * 第三方登录数据表 服务实现类
 * </p>
 *
 * @author author
 * @since 2024-06-29
 */
@Service
@AllArgsConstructor
public class ClientDetailsServiceImpl extends ServiceImpl<ClientDetailsMapper, ClientDetails> implements IClientDetailsService {

    private final RedisTool redisTool;
    private final TokenStorageUtil tokenStorageUtil;

    @Override
    public Result run(String appid) {
        ClientDetails one = this.getOne(new LambdaQueryWrapper<ClientDetails>()
            .eq(ClientDetails::getClientId, appid), false);
        if (Func.isNull(one)) {
            return R.fail(ResultCode.NOT_SEEK_RESOURCE, "未查询到对应配置数据");
        }
        String code = UUID.randomUUID().toString();
        redisTool.setCacheObject(GET_CODE + one.getClientId() + AuthUtil.getId(), code, 30, TimeUnit.MINUTES);
        return R.success(code);
    }

    @Override
    public Result getToken(String appid, String appSecret, String code) {
        if (Func.isNull(code) || Func.isNull(appid) || Func.isNull(appSecret)) {
            return R.fail(ResultCode.PARAMETER_NULL, "必要参数未传");
        }
        Object cacheObject = redisTool.getCacheObject(GET_CODE + appid + AuthUtil.getId());
        if (!Func.equals(cacheObject, cacheObject)) {
            return R.fail(ResultCode.FAIL, "临时凭证code错误");
        }
        ClientDetails clientDetails = this.getOne(new LambdaQueryWrapper<ClientDetails>()
            .eq(ClientDetails::getClientId, appid)
            .eq(ClientDetails::getClientSecret, appSecret), false);
        if (Func.isNull(clientDetails)) {
            return R.fail(ResultCode.NOT_SEEK_RESOURCE, "未查询到对应appid和appSecret相关数据");
        }
        UserInfo userInfo = new UserInfo()
            .setId(AuthUtil.getId()).setDeptId(AuthUtil.getDept()).setRoleId(AuthUtil.getRole());
        LoginVO loginVO = tokenStorageUtil.redisSaveToken(JSON.parseObject(JSON.toJSONString(userInfo)));
        return R.success(ResultCode.SUCCESS, "获取成功", loginVO);
    }

    @Override
    public Result listData(PageDTO pageDTO) {
        if (Func.isNull(pageDTO) || Func.equals(pageDTO.getPageNum(), 0) || Func.equals(pageDTO.getPageCurrent(), 0)) {
            return R.fail(ResultCode.PARAMETER_NULL, "必要参数未传");
        }
        Page<ClientDetails> page = this.page(new Page<>(pageDTO.getPageCurrent(), pageDTO.getPageNum()));
        return R.success(page);
    }

    @Override
    public Result getOneData(String id) {
        ClientDetails clientDetails = this.getOne(new LambdaQueryWrapper<ClientDetails>()
            .eq(ClientDetails::getId, id), false);
        return R.success(clientDetails);
    }

    @Override
    public Result addData(ClientDetails clientDetails) {
        if (Func.isNull(clientDetails.getClientId())) {
            clientDetails.setClientId(UUID.randomUUID().toString());
        }
        if (Func.isNull(clientDetails.getClientSecret())) {
            clientDetails.setClientSecret(UUID.randomUUID().toString());
        }
        clientDetails.setCreateTime(LocalDateTime.now());
        if (this.save(clientDetails)) {
            return R.success(ResultCode.SUCCESS_CREATE_RESOURCE, "新增成功");
        } else {
            return R.fail(ResultCode.INTERNAL_SERVER_ERROR, "新增失败,请联系管理人员");
        }
    }

    @Override
    public Result updateData(ClientDetails clientDetails) {
        if (Func.isNull(clientDetails) || Func.isNull(clientDetails.getId())) {
            return R.fail(ResultCode.PARAMETER_NULL, "必要参数未传");
        }
        if (this.updateById(clientDetails)) {
            return R.success(ResultCode.SUCCESS_CREATE_RESOURCE, "修改成功");
        } else {
            return R.fail(ResultCode.INTERNAL_SERVER_ERROR, "修改失败请联系管理人员");
        }
    }

    @Override
    @Transactional
    public Result deleteData(Long[] ids) {
        if (Func.isEmpty(ids)) {
            return R.fail(ResultCode.PARAMETER_NULL, "传入数据未空");
        }
        if (this.removeBatchByIds(Arrays.asList(ids))) {
            return R.success(ResultCode.SUCCESS_Non_Authoritative_Information, "删除成功");
        } else {
            return R.fail(ResultCode.INTERNAL_SERVER_ERROR, "删除失败请联系管理人员");
        }
    }
}
